<script lang="ts">
export const intervalOptions = [
  { label: '3小时', value: 3 },
  { label: '6小时', value: 6 },
];

export const forecastOptions = [
  { label: '7天', value: 7 },
  { label: '5天', value: 5 },
  { label: '3天', value: 3 },
];

export const sourceOptions = [
  { label: '海二代', value: '1' },
  { label: 'EC', value: '2' },
  { label: '中国气象局', value: '3' },
];

export const resolutionOptions = [
  { label: '0.25度', value: 0.25 },
  { label: '0.125度', value: 0.125 },
];

export const weatherOptions = [
  { label: '海面10米风', value: 1 },
  { label: '海浪', value: 2 },
  { label: '表层海流', value: 3 },
  { label: '海平面气压', value: 4 },
  { label: 'K指数', value: 8 },
  { label: '能见度', value: 5 },
  { label: '降水量', value: 6 },
  { label: '总(低)云量', value: 7 },
  { label: 'Cape指数', value: 9 },
  { label: '温度', value: 10 },
];
</script>

<script setup lang="ts">
import {
  ElButton, ElForm, ElMessage, FormInstance, FormRules,
  ElFormItem, ElInput, ElSelect, ElOption,
  ElCheckboxGroup, ElCheckbox,
} from 'element-plus';
import { initPoint, RegionPoint, pointValidator } from './RegionEditDialog.vue';
import { getLatFromBreakDown, getLonFromBreakDown, latBreakDown, lonBreakDown } from 'common/src/utils/lnglat';
import {getWeatherPack} from "common/src/apis";

interface Props {
  complete: () => void;
  update: (points: [number, number][]) => void;
}

interface WeatherConfig {
  topLeft: RegionPoint;
  bottomRight: RegionPoint;
  interval: number;
  forecast: number;
  source: string;
  resolution: number;
  weathers: number[];
}

const initWeatherConfig = (): WeatherConfig => {
  return {
    topLeft: { ...initPoint },
    bottomRight: { ...initPoint },
    interval: 3,
    forecast: 7,
    source: '1',
    resolution: 0.25,
    weathers: [],
  };
};

const props = withDefaults(defineProps<Props>(), {});
const formRef = ref<FormInstance>();
const loading = ref(false);
const show = ref(false);
const form = reactive<WeatherConfig>(initWeatherConfig());

const rules = reactive<FormRules>({
  interval: [
    { required: true, message: '请选择间隔时长', trigger: ['blur'] },
  ],
  forecast: [
    { required: true, message: '请选择预报天数', trigger: ['blur'] },
  ],
  source: [
    { required: true, message: '请选择数据源', trigger: ['blur'] },
  ],
  resolution: [
    { required: true, message: '请选择分辨率', trigger: ['blur'] },
  ],
});

const updateEditedRegion = () => {
  const { topLeft, bottomRight } = form;
  const points = [topLeft, bottomRight].map(point => {
    const { lonDegree, lonMinute, lonSecond, lonDir, latDegree, latMinute, latSecond, latDir } = point;
    const lon = getLonFromBreakDown(lonDir, lonDegree, lonMinute, lonSecond);
    const lat = getLatFromBreakDown(latDir, latDegree, latMinute, latSecond);
    return [lon, lat];
  }) as [number, number][];
  props.update(points);
};

const showDialog = (point: [[number, number], [number, number]]) => {
  Object.assign(form, initWeatherConfig());
  show.value = true;
  const [topLeft, bottomRight] = point;
  const [tlLonDegree, tlLonMinute, tlLonSecond, tlLonDir] = lonBreakDown(topLeft[0]);
  const [tlLatDegree, tlLatMinute, tlLatSecond, tlLatDir] = latBreakDown(topLeft[1]);
  form.topLeft = {
    lonDir: tlLonDir, latDir: tlLatDir,
    latDegree: String(tlLatDegree), lonDegree: String(tlLonDegree),
    latMinute: String(tlLatMinute), lonMinute: String(tlLonMinute),
    latSecond: String(tlLatSecond), lonSecond: String(tlLonSecond),
  };
  const [brLonDegree, brLonMinute, brLonSecond, brLonDir] = lonBreakDown(bottomRight[0]);
  const [brLatDegree, brLatMinute, brLatSecond, brLatDir] = latBreakDown(bottomRight[1]);
  form.bottomRight = {
    lonDir: brLonDir, latDir: brLatDir,
    latDegree: String(brLatDegree), lonDegree: String(brLonDegree),
    latMinute: String(brLatMinute), lonMinute: String(brLonMinute),
    latSecond: String(brLatSecond), lonSecond: String(brLonSecond),
  };
};

const handleSaveEdit = async () => {
  const valid = await formRef.value?.validate();
  if (!valid) return;
  loading.value = true;
  try {
    // 组装请求体（见图一字段约定）
    const tl = form.topLeft;
    const rb = form.bottomRight;
    const payload = {
      meteos: form.weathers,
      resolution: Number(form.resolution),
      taskLtLatitude: getLatFromBreakDown(tl.latDir!, Number(tl.latDegree), Number(tl.latMinute), Number(tl.latSecond)),
      taskLtLongitude: getLonFromBreakDown(tl.lonDir!, Number(tl.lonDegree), Number(tl.lonMinute), Number(tl.lonSecond)),
      taskRbLatitude: getLatFromBreakDown(rb.latDir!, Number(rb.latDegree), Number(rb.latMinute), Number(rb.latSecond)),
      taskRbLongitude: getLonFromBreakDown(rb.lonDir!, Number(rb.lonDegree), Number(rb.lonMinute), Number(rb.lonSecond)),
      hour: Number(form.interval),
      day: Number(form.forecast),
      source: Number(form.source), // 1: 海二代; 2: EC; 3: 中国气象局
    } as const;

    const resp: any = await getWeatherPack(payload);
    const url = resp?.data?.download_url ?? resp?.data?.url ?? resp?.download_url ?? resp?.url;
    if (!url) throw new Error('未返回下载地址');

    const fullUrl = String(url).startsWith('http')
      ? String(url)
      : `/node${String(url).startsWith('/') ? String(url) : `/${String(url)}`}`;

    // 触发浏览器下载
    const a = document.createElement('a');
    a.href = fullUrl;
    a.download = '';
    a.target = '_blank';
    document.body.appendChild(a);
    a.click();
    a.remove();

    loading.value = false;
    props.complete();
    show.value = false;
    ElMessage({ type: 'success', message: '导出成功' });
  } catch (err) {
    console.error(err);
    loading.value = false;
    ElMessage({ type: 'warning', message: '导出失败，请重试' });
  }
};

const handleCancelEdit = () => {
  show.value = false;
  props.complete();
};

defineExpose({ showDialog });
</script>

<template>
  <ElDialog
    :class="['custom-dialog', 'region-edit-dialog']"
    v-model="show"
    title="气象数据打包"
    width="650px"
    :modal="true"
    :close-on-click-modal="false"
    @close="() => handleCancelEdit()"
  >
    <ElForm ref="formRef" class="weather-select-form" :model="form" :rules="rules" style="padding-right: 16px;" label-position="left">
      <ElFormItem
        v-for="(point, idx) in [form.topLeft, form.bottomRight]"
        :prop="`point.${idx}`"
        class="region-point-item"
        :label="idx === 0 ? '左上角经纬度' : '右下角经纬度'"
        :rules="[
          { required: true, validator: (_rule: any, _value: any, callback: any) => pointValidator(point, callback) },
        ]"
      >
        <ElInput v-model.trim="point.latDegree" style="flex: 1; margin-right: 5px;" placeholder="纬度" @blur="() => updateEditedRegion()">
          <template #suffix>°</template>
        </ElInput>
        <ElInput v-model.trim="point.latMinute" style="width: 70px; margin-right: 5px;" placeholder="00" @blur="() => updateEditedRegion()">
          <template #suffix>'</template>
        </ElInput>
        <ElInput v-model.trim="point.latSecond" style="width: 70px; margin-right: 5px;" placeholder="00" @blur="() => updateEditedRegion()">
          <template #suffix>''</template>
        </ElInput>
        <span
          class="point-direction"
          @click="() => {
            point.latDir = point.latDir === 'N' ? 'S' : 'N';
            updateEditedRegion();
          }"
        >{{ point.latDir }}</span>
        <ElInput v-model.trim="point.lonDegree" style="flex: 1; margin-right: 5px;" placeholder="经度" @blur="() => updateEditedRegion()">
          <template #suffix>°</template>
        </ElInput>
        <ElInput v-model.trim="point.lonMinute" style="width: 70px; margin-right: 5px;" placeholder="00" @blur="() => updateEditedRegion()">
          <template #suffix>'</template>
        </ElInput>
        <ElInput v-model.trim="point.lonSecond" style="width: 70px; margin-right: 5px;" placeholder="00" @blur="() => updateEditedRegion()">
          <template #suffix>''</template>
        </ElInput>
        <span
          class="point-direction"
          @click="() => {
            point.lonDir = point.lonDir === 'E' ? 'W' : 'E';
            updateEditedRegion();
          }"
        >{{ point.lonDir }}</span>
      </ElFormItem>
      <ElFormItem class="form-row">
        <ElFormItem prop="resolution" label="空间分辨率" style="width: 180px;">
          <ElSelect
              v-model="form.resolution"
              popper-class="custom-select-popper"
              :clearable="false"
          >
            <ElOption
                v-for="option in resolutionOptions"
                :key="option.value"
                :value="option.value"
                :label="option.label"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem prop="forecast" label="预报时效" style="width: 180px;">
          <ElSelect
              v-model="form.forecast"
              popper-class="custom-select-popper"
              :clearable="false"
          >
            <ElOption
                v-for="option in forecastOptions"
                :key="option.value"
                :value="option.value"
                :label="option.label"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem prop="source" label="数据源" style="width: 220px;">
          <ElSelect
              v-model="form.source"
              popper-class="custom-select-popper"
              :clearable="false"
          >
            <ElOption
                v-for="option in sourceOptions"
                :key="option.value"
                :value="option.value"
                :label="option.label"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem prop="interval" label="时间分辨率" style="width: 180px;">
          <ElSelect
              v-model="form.interval"
              popper-class="custom-select-popper"
              :clearable="false"
          >
            <ElOption
                v-for="option in intervalOptions"
                :key="option.value"
                :value="option.value"
                :label="option.label"
            />
          </ElSelect>
        </ElFormItem>
      </ElFormItem>
      <ElFormItem prop="weathers" label="气象要素" required>
        <ElCheckboxGroup v-model="form.weathers">
          <ElCheckbox
            v-for="option in weatherOptions"
            :key="option.value"
            :value="option.value"
            :label="option.label"
            style="width: 100px;"
          />
        </ElCheckboxGroup>
      </ElFormItem>
    </ElForm>
    <div class="dialog-footer">
      <ElButton @click="() => handleCancelEdit()">取消</ElButton>
      <ElButton
        :loading="loading"
        type="primary"
        @click="() => handleSaveEdit()"
      >确定</ElButton>
    </div>
  </ElDialog>
</template>

<style lang="less" scoped>
.weather-select-form {
  .form-row {
    >:deep(.el-form-item__content) {
      display: flex;
      flex-flow:row wrap;
      justify-content: space-between;
    }
    :deep(.el-form-item) {
      margin-bottom: 10px;
    }
    :deep(.el-form-item__label){
      padding-right: 4px;
    }
  }
}
</style>
